/**
 * *
 * Copyright (c) 2010 readyState Software Ltd
 * 
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
 * applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, either express or implied. See the License for the specific
 * language governing permissions and limitations under the License.
 * 
*/
package com.readystatesoftware.mapviewballoons;

import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.google.android.maps.OverlayItem;

/**
 * A view representing a MapView marker information balloon.
 * 
* @author Jeff Gilfelt
 * 
*/
public class BalloonOverlayView<Item extends OverlayItem> extends FrameLayout
{

    private LinearLayout layout;
    private TextView title;
    private TextView snippet;
    private BalloonOverlayResources res;

    /**
     * Create a new BalloonOverlayView.
     *     
     * @param context - The activity context.
     * @param balloonBottomOffset - The bottom padding (in pixels) to be applied
     * when rendering this view.
     */
    public BalloonOverlayView(Context context, int balloonBottomOffset, BalloonOverlayResources res)
    {

        super(context);

        this.res = res;
        setPadding(10, 0, 10, balloonBottomOffset);

        layout = new LimitLinearLayout(context);
        layout.setVisibility(VISIBLE);

        setupView(context, layout);

        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        params.gravity = Gravity.NO_GRAVITY;

        addView(layout, params);

    }

    /**
     * Inflate and initialize the BalloonOverlayView UI. Override this method to
     * provide a custom view/layout for the balloon.
     *     
     * @param context - The activity context.
     * @param parent - The root layout into which you must inflate your view.
     */
    protected final void setupView(Context context, final ViewGroup parent)
    {

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflater.inflate(res.getLayout(), parent);
        title = (TextView) v.findViewById(res.getItemTitleId());
        snippet = (TextView) v.findViewById(res.getItemSnippetId());

        ImageView close = (ImageView) v.findViewById(res.getCloseId());
        close.setOnClickListener(new OnClickListener()
        {

            public void onClick(View v)
            {
                parent.setVisibility(GONE);
            }
        });

    }

    /**
     * Sets the view data from a given overlay item.
     *     
* @param item - The overlay item containing the relevant view data.
     */
    public void setData(Item item)
    {
        layout.setVisibility(VISIBLE);
        setBalloonData(item, layout);
    }

    /**
     * Sets the view data from a given overlay item. Override this method to
     * create your own data/view mappings.
     *     
     * @param item - The overlay item containing the relevant view data.
     * @param parent - The parent layout for this BalloonOverlayView.
     */
    protected void setBalloonData(Item item, ViewGroup parent)
    {
        if (item.getTitle() != null)
        {
            title.setVisibility(VISIBLE);
            title.setText(item.getTitle());
        }
        else
        {
            title.setText("");
            title.setVisibility(INVISIBLE);
        }
        if (item.getSnippet() != null)
        {
            snippet.setVisibility(VISIBLE);
            snippet.setText(item.getSnippet());
        }
        else
        {
            snippet.setText("");
            snippet.setVisibility(INVISIBLE);
        }
    }

    private class LimitLinearLayout extends LinearLayout
    {

        private static final int MAX_WIDTH_DP = 280;
        final float SCALE = getContext().getResources().getDisplayMetrics().density;

        public LimitLinearLayout(Context context)
        {
            super(context);
        }

        public LimitLinearLayout(Context context, AttributeSet attrs)
        {
            super(context, attrs);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
        {
            int mode = MeasureSpec.getMode(widthMeasureSpec);
            int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
            int adjustedMaxWidth = (int) (MAX_WIDTH_DP * SCALE + 0.5f);
            int adjustedWidth = Math.min(measuredWidth, adjustedMaxWidth);
            int adjustedWidthMeasureSpec = MeasureSpec.makeMeasureSpec(adjustedWidth, mode);
            super.onMeasure(adjustedWidthMeasureSpec, heightMeasureSpec);
        }
    }
}